﻿using DocumentGeneratorPlugins;
using OpenXmlDocumentGenerator;
using OpenXMLDocumentGenerator.Helpers;
using OpenXMLDocumentGenerator.Model;
using SQLDocumentor.SQLModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLDocumentor
{
    public class SQLServerDocumentor:ISystemDocumentor
    {
        public DocumentorLog.Logger Log
        {
            get {
                return DocumentorLog.Logger.Current;
            }
        }

        public event DocumentGeneratorEventHandler DocumentGeneratorEvent;

        public void GenerateDocument(IDocumentOptions options)
        {
            OnDocumentGeneratorEvent("Get SQL information", StateStep.Start);
            Log.Info("Start Farm Documentor");
            SQLDocumentOption sqlOption= options as SQLDocumentOption;
            SQLHelpers.SQLServerLoader.SQLEvent += SQLServerLoader_SQLEvent;
            SQLServer srv= SQLHelpers.SQLServerLoader.Current.LoadSqlServer(sqlOption);
            string strPathzip= options.DocumentPath.Replace("docx", "documentor");
            ZipSerializer.Serialize(srv, strPathzip);
            OnDocumentGeneratorEvent("Start Creating Document", StateStep.Progress);
            WordDocumentHelpers wdh = new WordDocumentHelpers();
            wdh.CreatePackage(options);
            wdh.AddTitleParagraph(options.DocumentPropertiesTitle);
            SQLServerOverView(srv, wdh);
            SQLServerDBInformation(srv.Databases, wdh);
            wdh.Dispose();
            OnDocumentGeneratorEvent("Finish Creating Document", StateStep.Finish);
            
        }

        void SQLServerLoader_SQLEvent(object sender, SQLHelpers.SQLInfoEventArgs fea)
        {
            OnDocumentGeneratorEvent(fea.Message, StateStep.Progress);
        }

        private void SQLServerDBInformation(SQLDatabase[] sQLDatabase, WordDocumentHelpers wdh)
        {
            wdh.AddHeader1Paragraph("Base de données");
            foreach (SQLDatabase db in sQLDatabase)
            {
                wdh.AddHeader2Paragraph(db.Name);
                wdh.AddNormalParagraph();
                wdh.AddNormalParagraph();
                wdh.AddTextBold("Log File: ");
                
                PropertyModel[] pms = RenderTypeHelper.GetPropertyFromObject(db, new string[] { "Name", "Tables", "Roles", "LogFiles", "Users","StoredProcedures" });
                RenderTypeHelper.RenderPropertyModelForTable(pms, wdh);
                SQLServerLogFileInformation(db.LogFiles, wdh);
                SQLServerTableInformation(db.Tables, wdh);
                SQLServerSPInformation(db.StoredProcedures, wdh);
                wdh.AddNormalParagraph();
            }
        }

        private void SQLServerLogFileInformation(SQLLogFile[] sQLLogFile, WordDocumentHelpers wdh)
        {
            wdh.AddHeader3Paragraph("Log Files");
            foreach (SQLLogFile lf in sQLLogFile)
            {
                wdh.AddHeader4Paragraph(lf.Name);
                wdh.AddNormalParagraph();
                PropertyModel[] pms = RenderTypeHelper.GetPropertyFromObject(lf, new string[] {"Name" });
                RenderTypeHelper.RenderPropertyModelForTable(pms, wdh);
                wdh.AddNormalParagraph();
            }
        }

        private void SQLServerSPInformation(SQLStoredProcedure[] sQLStoredProcedure, WordDocumentHelpers wdh)
        {
            wdh.AddHeader3Paragraph("Stored Procedure");
            foreach (SQLStoredProcedure sp in sQLStoredProcedure)
            {
                wdh.AddHeader4Paragraph(sp.Name);
                wdh.AddNormalParagraph();
                PropertyModel[] pms = RenderTypeHelper.GetPropertyFromObject(sp, new string[] { "Columns", "Name" });
                RenderTypeHelper.RenderPropertyModelForTable(pms, wdh);
                wdh.AddNormalParagraph();
            }
        }

        private void SQLServerTableInformation(SQLTable[] sQLTable, WordDocumentHelpers wdh)
        {
            wdh.AddHeader3Paragraph("Tables");
            foreach (SQLTable tbl in sQLTable)
            {
                wdh.AddHeader4Paragraph(tbl.Name);
                wdh.AddNormalParagraph();
                PropertyModel[] pms = RenderTypeHelper.GetPropertyFromObject(tbl, new string[] { "Columns", "Name" });
                RenderTypeHelper.RenderPropertyModelForTable(pms, wdh);
                SQLServerColumnInformation(tbl.Columns, wdh);
                wdh.AddNormalParagraph();
            }
        }

        private void SQLServerColumnInformation(SQLColumn[] sQLColumn, WordDocumentHelpers wdh)
        {

            wdh.AddHeader5Paragraph("Columns");
            foreach (SQLColumn col in sQLColumn)
            {
               
                wdh.AddHeader6Paragraph(col.Name);
                wdh.AddNormalParagraph();
                PropertyModel[] pms = RenderTypeHelper.GetPropertyFromObject(col, new string[] { "Name" });
                RenderTypeHelper.RenderPropertyModelForTable(pms, wdh);
                wdh.AddNormalParagraph();
            }
        }

        private void SQLServerOverView(SQLServer srv, WordDocumentHelpers wdh)
        {
            wdh.AddHeader1Paragraph("Apercu de l'infrastructure SQL Server");
            wdh.AddNormalParagraph();
            wdh.AddTextBold("SQL Server: ");
            wdh.AddBreak();
            wdh.AddText(srv.Product);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Niveau: ");
            wdh.AddBreak();
            wdh.AddText(srv.ProductLevel);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Version de SQL Server: ");
            wdh.AddBreak();
            wdh.AddText(srv.Version.ToString());
            
            wdh.AddNormalParagraph();
            wdh.AddTextBold("Edition: ");
            wdh.AddBreak();
            wdh.AddText(srv.Edition);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Collation: ");
            wdh.AddBreak();
            wdh.AddText(srv.Collation);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Racine: ");
            wdh.AddBreak();
            wdh.AddText(srv.RootDirectory);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Compte de service: ");
            wdh.AddBreak();
            wdh.AddText(srv.ServiceAccount);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Nom du service: ");
            wdh.AddBreak();
            wdh.AddText(srv.ServiceName);

            wdh.AddNormalParagraph();
            wdh.AddTextBold("Demarrage du service: ");
            wdh.AddBreak();
            wdh.AddText(srv.ServiceStartMode);

            //TODO: add instance name
            
            
        }

        protected virtual void OnDocumentGeneratorEvent(String Message, StateStep Step)
        {
            if (DocumentGeneratorEvent != null)
            {
                DocumentGeneratorEventArgs dgea = new DocumentGeneratorEventArgs();
                dgea.Message = Message;
                dgea.State = Step;
                DocumentGeneratorEvent(this, dgea);
            }
        }
        public IDocumentOptions CreateDocumentOption()
        {
            return new SQLDocumentOption();
        }

        public string PluginName
        {
            get { return "SQL Server Documentor"; }
        }

        public System.Windows.Controls.UserControl GetUserInterface()
        {
            return (System.Windows.Controls.UserControl)(new SQLDocumentor.UI.SQLDocumentorUI(this));
        }
    }
}
